Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wrap doRequest calls for error handling #11158

Merged
merged 3 commits into from
Sep 29, 2021
Merged

wrap doRequest calls for error handling #11158

merged 3 commits into from
Sep 29, 2021

Conversation

acpana
Copy link
Contributor

@acpana acpana commented Sep 27, 2021

Overview

This PR builds on #11054 to wrap all remaining doRequest() calls around a require*() call.

Issue Related

#10865

Notes:

  • mostly refactoring, no logic changes

PR Checklist

  • go fmt
  • go mod
  • n/a pr/changelog -- no "public" api changes

Signed-off-by: FFMMM <FFMMM@users.noreply.github.com>
Signed-off-by: FFMMM <FFMMM@users.noreply.github.com>
@github-actions github-actions bot added the theme/api Relating to the HTTP API interface label Sep 27, 2021
@acpana acpana added the pr/no-changelog PR does not need a corresponding .changelog entry label Sep 27, 2021
Copy link
Contributor

@freddygv freddygv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for following up here! I left some questions below

api/kv.go Show resolved Hide resolved
api/agent.go Show resolved Hide resolved
api/agent.go Show resolved Hide resolved
api/agent.go Outdated Show resolved Hide resolved
api/agent.go Outdated Show resolved Hide resolved
Signed-off-by: FFMMM <FFMMM@users.noreply.github.com>
@kisunji
Copy link
Contributor

kisunji commented Sep 29, 2021

@FFMMM Given some of the complexity that arose from this PR I think there's some refactoring that may need to be done for requireOK + requireHttpStatusCodes.

Both functions take d time.Duration, resp *http.Response, e error which isn't great but it felt ergonomic to wrap doRequest like requireOK(c.doRequest). Note that d isn't used and non-nil e is simply returned back to the caller with the side effect of closing resp.

Currently require* can return 1) the transport-level error from doRequest; or 2) api.StatusError. These lines suggest to me there are cases where it's better to handle the error from doRequest (1) explicitly first before calling requireOK to extract api.StatusError (2), if any.

This would mean we'd have to make the handling a bit more verbose on all of the call sites, for example:

_, resp, err := c.doRequest(r)
if err != nil {
    return nil, fmt.Errorf("error making request: %w", err) // distinguish errors from doRequest
}
if err := requireOK(resp); err != nil {
    return nil, err         // this came from the response, meaning doRequest succeeded
}
defer closeResponseBody(resp)

Does this make sense? cc @dnephin

@dnephin
Copy link
Contributor

dnephin commented Sep 29, 2021

I haven't had a chance to catch up on this discussion, but I think that suggested refactor makes sense at a high level. Assuming the common case is requireOk we could even add a doRequestAndRequireOk that contains most of those lines. For the few places that don't call requireOk we can keep them as separate calls.

@acpana
Copy link
Contributor Author

acpana commented Sep 29, 2021

hey @kisunji and @dnephin thank y'all for chiming in! let me agree with y'all below with some context and proposed path:

I think there's some refactoring that may need to be done for requireOK + requireHttpStatusCodes.

Yes that's actually something that @markan and I were chatting about when looking at the api/agent.go code. It's weird ergonomics that the require() funcs close the response body for doRequest errors and not for other errors.

I think I'd love to have a chance to address this refactor in a subsequent PR.

Assuming the common case is requireOk we could even add a doRequestAndRequireOk that contains most of those lines.

There's actually >130 usages of requireOK() calls when I looked at that yesterday. I'd argue that a refactor that does doRequestAndRequireOk would be a big diff and even one that touches the internals of requireOK to modify behavior would warrant its own separate PR.


I'm hoping that we can merge this PR if it makes sense and I can take on the work to have a stab at refactoring the code in a subsequent PR. What do y'all think? 👍🏼 or 👎🏼 ?

Copy link
Contributor

@kisunji kisunji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable to defer the refactor to another PR!

low-prio todos from my perspective:

  • revisit error-handling of requireOK to be more clear/explicit
  • use api.StatusError in all fmt.Errorf's where we embed the status code in the error message

@acpana acpana merged commit 8bb6d85 into main Sep 29, 2021
@acpana acpana deleted the ffmmm/f-10865 branch September 29, 2021 20:12
@hc-github-team-consul-core
Copy link
Contributor

🍒 If backport labels were added before merging, cherry-picking will start automatically.

To retroactively trigger a backport after merging, add backport labels and re-run https://circleci.com/gh/hashicorp/consul/461161.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr/no-changelog PR does not need a corresponding .changelog entry theme/api Relating to the HTTP API interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants